<template>
  <div class="visual" :style="{width}">
    <div v-show="!shrink">
      <div class="title black">
        <h4>可视化</h4>
        <div @click="setShrink(true)">
          <img class="shrink-image" src="@/assets/image/common/右拉.png" />
        </div>
      </div>
      <div class="content">
        <div v-for="img in imgList" :key="img.type" @click="setChartActive(img.type)">
          <img :src="img.img" :title="img.name" v-show="img.type != activeType" />
          <img :src="img.imgActive" :title="img.name" v-show="img.type == activeType" />
        </div>
      </div>

      <div class="active-box" v-show="hasActive">
        <div class="field">
          <span>轴</span>
          <div
            class="axis"
            @drop="drop($event, 'axis')"
            @dragover="allowDrop"
            v-if="getChartActive"
          >
            <span v-if="getChartActive.axis.length <= 0">在此处拖动数据字段</span>
            <span v-else>
              <div v-for="(axis, index) in getChartActive.axis" :key="index" class="field-item">
                <span>{{ axis.fieldName }}</span>
                <span>
                  <img @click="removeField('axis', index)" src="@/assets/image/main/关闭.png" />
                </span>
              </div>
            </span>
          </div>
          <visual-field-list
            :name="'值'"
            :getChartActive="getChartActive"
            :type="'value'"
            v-on:get-field-type="getFeildType"
            v-on:check-field-type="checkFieldType"
            v-on:set-way="setWay"
            v-on:drop="drop"
            v-on:remove-field="removeField"
            v-on:allow-drop="allowDrop"
          ></visual-field-list>

          <div v-if="getChartActive != null && getChartActive.type=='forecast'">
            <span>预测</span>
            <div
              class="value"
              @drop="drop($event, 'forecast')"
              @dragover="allowDrop"
              v-if="getChartActive"
            >
              <span v-if="getChartActive != null && getChartActive.forecast.length <= 0">在此处拖动数据字段</span>
              <span v-else>
                <div
                  v-for="(forecast, index) in getChartActive.forecast"
                  :key="index"
                  class="field-item"
                >
                  <span>{{ forecast.fieldName }}</span>
                  <span>
                    <img @click="removeField('forecast', index)" src="@/assets/image/main/关闭.png" />
                  </span>
                </div>
              </span>
            </div>
          </div>
        </div>

        <cluster-paramter-tools
          v-if="getChartActive && getChartActive.type == 'cluster'"
          :clusterCount="getChartActive.clusterCount"
        ></cluster-paramter-tools>
        <title-tools
          v-if="getChartActive"
          :fontsize="getChartActive.fontsize"
          :title="getChartActive.title"
          :titleLeft="getChartActive.titleLeft"
          :titleColor="getChartActive.titleColor"
        ></title-tools>

        <x-axis-tools
          v-if="getChartActive"
          :xAxisShow="getChartActive.xAxisShow"
          :xAxisName="getChartActive.xAxisName"
          :nameLocation="getChartActive.xAxisNameLocation"
          :offset="getChartActive.xAxisOffset"
          :position="getChartActive.xAxisPosition"
          :color="getChartActive.xAxisNameColor"
          :fontSize="getChartActive.xAxisFontSize">
        </x-axis-tools>

        <y-axis-tools
          v-if="getChartActive"
          :yAxisShow="getChartActive.yAxisShow"
          :yAxisName="getChartActive.yAxisName"
          :nameLocation="getChartActive.yAxisNameLocation"
          :offset="getChartActive.yAxisOffset"
          :position="getChartActive.yAxisPosition"
          :color="getChartActive.yAxisNameColor"
          :fontSize="getChartActive.yAxisFontSize">
        </y-axis-tools>

        <legend-tools 
          v-if="getChartActive"
          :legendType="getChartActive.legendType"
          :legendShow="getChartActive.legendShow"
          :legendLeft="getChartActive.legendLeft"
          :legendTop="getChartActive.legendTop"
          :legendWidth="getChartActive.legendWidth"
          :legendHeight="getChartActive.legendHeight"
          :legendOrient="getChartActive.legendOrient"
          :legendColor="getChartActive.legendColor"
          :legendFontSize="getChartActive.legendFontSize">

        </legend-tools>
      </div>

      <theme-tools :darkModel="getDarkMode"></theme-tools>
    </div>

    <div v-show="shrink" style="color:white;background-color:rgb(33, 33, 33);height:100%;">
      <div @click="setShrink(false)">
        <img style="padding:5px;width:25px;" src="@/assets/image/common/左拉.png" />
      </div>

      <h4 style="padding:10px;">可视化</h4>
    </div>
  </div>
</template>

<script>
import TitleTools from "@/components/visual/TitleTools.vue";
import ClusterParamterTools from "@/components/visual/ClusterParamterTools.vue";
import VisualFieldList from "@/components/visual/VisualFieldList";
import ThemeTools from "@/components/visual/ThemeTools";
import XAxisTools from "@/components/visual/XAxisTools";
import YAxisTools from "@/components/visual/YAxisTools";
import LegendTools from "@/components/visual/LegendTools"
export default {
  components: {
    TitleTools,
    ClusterParamterTools,
    VisualFieldList,
    ThemeTools,
    XAxisTools,
    YAxisTools,
    LegendTools,
  },
  props: ["chartActive", "canvasSizeStatus"],
  data() {
    return {
      width: "12%",
      imgList: [
        {
          imgActive: require("@/assets/image/chart/条形图-灰色.png"),
          img: require("@/assets/image/chart/条形图-彩色.png"),
          name: "柱状图",
          type: "bar",
        },
        {
          imgActive: require("@/assets/image/chart/条形图 -横向-灰色(1).png"),
          img: require("@/assets/image/chart/条形图-横向-彩色.png"),
          name: "横向-柱状图",
          type: "bar-cross",
        },
        {
          imgActive: require("@/assets/image/chart/图表-折线图-灰色.png"),
          img: require("@/assets/image/chart/图表-折线图-彩色.png"),
          name: "折线图",
          type: "line",
        },
        {
          imgActive: require("@/assets/image/chart/散点-灰色.png"),
          img: require("@/assets/image/chart/散点.png"),
          name: "散点图",
          type: "scatter",
        },
        {
          imgActive: require("@/assets/image/chart/面积图.-灰色.png"),
          img: require("@/assets/image/chart/面积图.png"),
          name: "面积图",
          type: "area",
        },
        {
          imgActive: require("@/assets/image/chart/饼图 灰色.png"),
          img: require("@/assets/image/chart/饼图 彩色.png"),
          name: "饼图",
          type: "pie",
        },
        {
          imgActive: require("@/assets/image/chart/拟合线.png"),
          img: require("@/assets/image/chart/拟合线-黑色.png"),
          name: "拟合",
          type: "matching",
        },
        {
          imgActive: require("@/assets/image/chart/聚类-灰色.png"),
          img: require("@/assets/image/chart/聚类.png"),
          name: "聚类",
          type: "cluster",
        },
        {
          imgActive: require("@/assets/image/chart/预测-灰色.png"),
          img: require("@/assets/image/chart/预测.png"),
          name: "预测",
          type: "forecast",
        },
      ],
      sigleFieldList: ["pie", "matching", "cluster", "forecast"],
      activeType: null,
      columns: [],
      values: [],
      moreShow: false,
      shrink: false,
      wayActive: "sum",
      wayList: [
        {
          label: "求和",
          value: "sum",
        },
        {
          label: "平均值",
          value: "mean",
        },
        {
          label: "最小值",
          value: "min",
        },
        {
          label: "最大值",
          value: "max",
        },
        {
          label: "计数（非重复）",
          value: "countNR",
        },
        {
          label: "计数",
          value: "count",
        },
        {
          label: "标准方差",
          value: "std",
        },
        {
          label: "方差",
          value: "var",
        },
      ],
    };
  },
  watch: {
    chartActiveAxis(val) {
      if (!val) return;

      let sheetName = val.sheetName;
      let fieldName = val.fieldName;

      let type = this.getFeildType(sheetName, fieldName);

      this.checkFieldType(type);
    },
    getChartActive(val) {
      if (val == null) {
        this.activeType = null;
      } else {
        this.activeType = val.type;
      }
    },
  },
  computed: {
    hasActive() {
      return this.$store.getters.getChartActiveIndex >= 0;
    },
    getChartActive() {
      return this.$store.getters.getChartActive;
    },
    getWayList() {
      return function (index) {
        let valueSheetName = this.getChartActive.value[0].sheetName;
        let valueFieldName = this.getChartActive.value[index].fieldName;
        let fieldType = this.getFeildType(valueSheetName, valueFieldName);

        this.checkFieldType(fieldType);
      };
    },
    getDarkMode() {
      return this.$store.state.theme.darkMode;
    },
    canCompute() {
      if (this.getChartActive.type == "forecast")
        return (
          this.getChartActive.axis.length > 0 &&
          this.getChartActive.value.length > 0 &&
          this.getChartActive.forecast.length > 0
        );

      return (
        this.getChartActive.axis.length > 0 &&
        this.getChartActive.value.length > 0
      );
    },
    chartActiveAxis() {
      let chartActive = this.$store.getters.getChartActive;
      return chartActive ? chartActive.value[0] : null;
    },
    cahrtActiveWay() {
      return this.getChartActive.way;
    },
  },
  methods: {
    setChartActive(type) {
      let index = this.$store.getters.getChartActiveIndex;

      if (index == -1) {
        this.activeType = type;

        let data = {
          type,
          width: 300,
          height: 300,
          theX: 0,
          theY: 0,
          way: null,
          title: "",
          titleLeft: 30,
          titleColor: '#2260C2',
          values: [],
          columns: [],
          axis: [],
          value: [],
          forecast: [],
          xAxisShow:true,
          xAxisName:"",
          xAxisNameLocation:"end",
          xAxisNameColor:"rgba(0, 0, 0, 1)",
          xAxisOffset: 0,
          xAxisFontSize:12,
          xAxisPosition: 'bottom',
          yAxisShow: true,
          yAxisName: "",
          yAxisNameLocation:"end",
          yAxisNameColor:"rgba(0, 0, 0, 1)",
          yAxisOffset: 0,
          yAxisFontSize:12,
          yAxisPosition: "bottom",

          legendType: "scroll",
          legendShow: true,
          legendLeft: 0,
          legendTop:0,
          legendWidth:100,
          legendHeight:100,
          legendOrient:'vertical',
          legendColor: '#333',
          legendFontSize: 12,
          
          fontsize: 12,
          zindex: 101,
          clusterCount: 3,
          echarts: null,
          darkMode: false,
          active: true,
          moveActive: false,
        };

        this.$store.commit("addChartList", data);
      } else {
        let valueLen = this.getChartActive.value.length;
        let sigleIndex = this.sigleFieldList.indexOf(type);

        //如果要切换的图表类型仅支持单值并且当前表存在多值时提示切换失败
        if (sigleIndex != -1 && valueLen > 1) {
          this.$message.error("切换的表只支持单字段值");
          return;
        }
        this.activeType = type;

        let data = {
          type,
          chartActiveIndex: index,
        };
        this.$store.commit("setChartType", data);
      }
    },
    setWay(index, value) {
      this.wayActive = value;
      this.moreShow = false;

      let data = {
        index,
        value,
      };
      this.$store.commit("setWayType", data);

      if (this.canCompute) {
        let data = {
          columns: this.getChartActive.axis,
          values: this.getChartActive.value,
          way: this.wayActive,
        };

        this.compute(data);
      }
    },
    getFeildType(sheetName, fieldName) {
      let loadSheetList = this.$store.state.loadSheet.loadSheetList;
      let types = [];
      let columns = [];
      for (let loadSheet of loadSheetList) {
        if (loadSheet.showName == sheetName) {
          types = loadSheet.types;
          columns = loadSheet.columns;
        }
      }

      for (let i = 0; i < columns.length; i++) {
        if (columns[i] == fieldName) {
          return types[i];
        }
      }

      return null;
    },
    checkFieldType(type) {
      if (type == "object" || type == "category") {
        let wayList = [
          {
            label: "计数",
            value: "count",
          },
          {
            label: "计数（非重复）",
            value: "countNR",
          },
        ];
        this.wayActive = "count";
        this.wayList = wayList;

        return wayList;
      } else {
        this.wayActive = "sum";

        this.wayList = [
          {
            label: "求和",
            value: "sum",
          },
          {
            label: "平均值",
            value: "mean",
          },
          {
            label: "最小值",
            value: "min",
          },
          {
            label: "最大值",
            value: "max",
          },
          {
            label: "计数（非重复）",
            value: "countNR",
          },
          {
            label: "计数",
            value: "count",
          },
          {
            label: "标准方差",
            value: "std",
          },
          {
            label: "方差",
            value: "var",
          },
        ];

        return this.wayList;
      }
    },
    removeField(type, index) {
      let data = {
        type,
        index,
      };

      this.$store.commit("removeChartField", data);

      data = {
        columns: this.getChartActive.axis,
        values: this.getChartActive.value,
        way: this.wayActive,
      };

      this.compute(data);
    },
    allowDrop(e) {
      e.preventDefault();
    },
    hasSingleField() {
      let sigleFieldList = this.sigleFieldList;

      for (let sigleField of sigleFieldList)
        if (this.activeType == sigleField) return true;
    },
    compute(data) {
      this.$store.commit("setCharLoading", true);
      this.$store.commit("setChartWay", data.way);

      if (this.activeType == "matching") data.matching = true;

      if (this.activeType == "forecast") data["has_forecast"] = true;
      else data["has_forecast"] = false;

      this.$axios.post("/compute", data).then((res) => {
        if (res.code == 200) {
          this.$message({
            type: "success",
            message: res.msg,
          });

          this.$store.commit("setChartColumnsAndValues", res.data);
          this.$store.commit("setCharLoading", false);
        } else {
          this.$message.error(res.msg);
        }
      });
    },
    drop(e, type) {
      e.preventDefault();

      let field = e.dataTransfer.getData("field");
      let sheetName = e.dataTransfer.getData("sheetName");
      let hasSingle = this.hasSingleField();

      let fieldType = this.getFeildType(sheetName, field);
      this.checkFieldType(fieldType);
      let wayType = this.wayActive;
      let data = {
        type,
        wayType,
        sheetName,
        hasSingle,
        fieldName: field,
      };

      this.$store.commit("setChartField", data);

      //如果轴和值都有字段，那么就调用后端的进行分析
      if (this.canCompute) {
        let valueSheetName = this.getChartActive.value[0].sheetName;
        let valueFieldName = this.getChartActive.value[0].fieldName;
        let fieldType = this.getFeildType(valueSheetName, valueFieldName);
        this.checkFieldType(fieldType);

        this.$store.commit("setChartTitle", this.wayActive);

        let data = {
          columns: this.getChartActive.axis,
          values: this.getChartActive.value,
          forecast: this.getChartActive.forecast,
          way: this.wayActive,
        };

        this.compute(data);
      }
    },
    setShrink(val) {
      this.shrink = val;

      if (val) this.width = "3%";
      else this.width = "12%";

      this.$emit("set-canvas-size-status", this.canvasSizeStatus + 1);
    },
  },
};
</script>

<style scoped>
.title {
  padding: 12px;

  border-bottom: 1px solid black;

  text-align: left;
}

.hiden {
  visibility: hidden;
}

.show {
  visibility: visible;
}

.title {
  display: flex;
  justify-content: space-between;

  background-color: rgb(33, 33, 33);
}

.title h4 {
  margin: 0;
}

.black {
  background-color: rgb(33, 33, 33);
  color: white;
}

.visual {
  background-color: rgb(33, 33, 33);
  border-left:1px solid black;
  overflow-y: auto;
}

.shrink-image {
  width: 15px;
}

.content {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;

  padding-top: 2px;
  padding-left: 10px;
}

.content > div {
  width: 15%;
  margin-right: 4px;
}
.content img {
  width: 100%;
}

.field {
  user-select: none;
  padding: 8px;

  color: gray;
}

.axis,
.value {
  border: 1px gray;
  border-style: dashed;

  padding: 5px;
  margin-bottom: 15px;
}

.field-item {
  display: flex;
  justify-content: space-between;
  align-items: center;

  color: white;
  background-color: rgb(51, 51, 51);
  padding: 4px;
  border: 1px solid black;
  border-radius: 4px;
  margin-bottom: 3px;
}

.field-item span {
  display: flex;
  align-items: center;
}

.field-item img {
  width: 20px;
}

.pull-down {
  position: relative;
}

.moreBox {
  position: absolute;
  top: 8px;
  left: -150px;

  list-style-type: none;
  padding: 0;
  background-color: white;
  border: 1px solid black;

  color: black;

  width: 200px;

  z-index: 20;
}

.moreBox li {
  padding: 5px;

  text-align: start;
}

.moreBox li:hover {
  background-color: rgb(200, 200, 200);
}
</style>